package com.oceansoft.mobile.econsole.task.sms;

import com.alibaba.fastjson.JSONArray;
import com.oceansoft.mobile.econsole.common.constant.ConfigInfo;
import com.oceansoft.mobile.econsole.common.constant.Constant;
import com.oceansoft.mobile.econsole.modules.accident.entity.AccidentInfo;
import com.oceansoft.mobile.econsole.modules.accident.persistence.IAccidentMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ScheduleTasker {

    private static final int STEP = 30;//30秒一次
    private static final int MAX_COUNT = 10;//最大访问10次   就是300秒   5分钟
    private Logger logger = LoggerFactory.getLogger(ScheduleTasker.class.getName());
    private ConfigInfo mConfigInfo;
    private int mCounter; //任务调度次数计数器
    private int corePoolSize = 10;
    private ScheduledThreadPoolExecutor scheduler;
    private String mBizPrimary; //业务组件
    private Date mQueryStartTime;//短信回复起始时间
    private int mTimeOffset = 360;//时间查询偏移量，默认为6分钟
    private IAccidentMapper mAccidenMapper;
    private AccidentInfo mAccidentInfo;

    public ScheduleTasker(String bizPrimaryKey, Date queryStartTime, int timeOffset, ConfigInfo configInfo, AccidentInfo accidentInfo, IAccidentMapper accidentMapper) {
        this.mCounter = 0;
        this.mBizPrimary = bizPrimaryKey;
        this.mQueryStartTime = queryStartTime;
        this.mTimeOffset = timeOffset;
        this.mConfigInfo = configInfo;
        this.mAccidentInfo = accidentInfo;
        this.mAccidenMapper = accidentMapper;
        scheduler = new ScheduledThreadPoolExecutor(corePoolSize);
    }

    private void schedule(Runnable event, long delay) {
        scheduler.schedule(event, delay, TimeUnit.SECONDS);
    }

    /**
     * 启动定时器接收短信
     */
    public void startTask() {
        this.schedule(new Runnable() {
            public void run() {
                getReplySMS(mBizPrimary);
            }
        }, STEP);
    }

    /**
     * 获取回复短信
     *
     * @param primaryKey 业务主键
     */
    private void getReplySMS(final String primaryKey) {
        //超过时间直接返回格式2短信
        if (mCounter >= MAX_COUNT) {
            SMSUtil.sendSMS(primaryKey, this.mConfigInfo.getAccidentUnConfirm(primaryKey), (mAccidentInfo.getTelA() + "," + mAccidentInfo.getTelB()));
            //将通知当事去理赔中心处理，同时更改事故状态为已完成
            logger.debug("\n回复超时,返回格式2信息，轮询次数======>" + mCounter);
            mAccidenMapper.updateAccidentBaseInfoHandlerAndStatus(primaryKey, Constant.ACCIDENT_PROCESS_OFFICE, AccidentInfo.STATUS_COMPLETE);
            this.scheduler.shutdown();
            return;
        }
        //计算查询日期
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(mQueryStartTime);
        Calendar startCal = Calendar.getInstance();
        startCal.add(Calendar.SECOND, -mTimeOffset);
        String startTimeStr = DatetimeUtil.dateToStr(startCal.getTime(), "yyyyMMddHHmmss");
        Calendar endCal = Calendar.getInstance();
        endCal.add(Calendar.SECOND, mTimeOffset);
        DatetimeUtil.dateToStr(endCal.getTime(), "yyyyMMddHHmmss");
        String endTimeStr = DatetimeUtil.dateToStr(endCal.getTime(), "yyyyMMddHHmmss");
        String receiveMessage = SMSUtil.receiveSMS(startTimeStr, endTimeStr);
        logger.debug("\n轮询次数" + mCounter + ";    \n接收短信时间参数区间" + startTimeStr + "---->" + endTimeStr + ";   \n短信回复内容：" + receiveMessage);
        //两个人均未回复
        if (!StringUtils.hasText(receiveMessage)) {
            logger.debug("\n当事人均未回复事故责任确认信息，事故编号:" + primaryKey);
            this.schedule(new Runnable() {
                public void run() {
                    getReplySMS(primaryKey);
                }
            }, STEP);
            mCounter++;
            return;
        }
        try {
            //用于保存收到的需要的所有信息
            String[] contents = new String[2];
            List<MessReceive> list = JSONArray.parseArray(receiveMessage, MessReceive.class);
            int k = 0;
            //判断两位当事人是否全部回复
            for (MessReceive messReceive : list) {
                String pk_ = messReceive.getBusinesspk();
                logger.debug("\n已从短信接口查询到事故信息，事故编号:" + primaryKey + "；短信事故编号：" + pk_);
                if (k >= 2) //两人均回复
                    break;
                if (primaryKey.equals(pk_)) {
                    logger.debug("已匹配事故当事人之一，匹配短信内容为：" + messReceive.getContent());
                    contents[k] = messReceive.getContent().trim();
                    k++;
                }
            }
            if (k < 2) {//其中一位当事人未回复短信，则继续下一次任务调度，直至超时
                logger.debug("其中一位当事人未回复短信，继续下一次任务调度，当前轮询数次：" + mCounter);
                this.schedule(new Runnable() {
                    public void run() {
                        getReplySMS(primaryKey);
                    }
                }, STEP);
                mCounter++;
                return;
            }
            //此处两位当事人均已回复，则开始检测回复内容情况
            if ("1".equals(contents[0]) && "1".equals(contents[1])) {
                //两个当事人均回复1，发送格式一短信
                SMSUtil.sendSMS(primaryKey, this.mConfigInfo.getAccidentConfirmSMS(primaryKey), (mAccidentInfo.getTelA() + "," + mAccidentInfo.getTelB()));
                logger.debug("两个当事人均回复1，发送格式一短信");
                //更改事故状态为已完成
                mAccidenMapper.updateAccidentBaseInfoHandlerAndStatus(primaryKey, Constant.ACCIDENT_PROCESS_NEGOTIATE, AccidentInfo.STATUS_COMPLETE);
                logger.debug("更改事故状态为已完成");
                this.scheduler.shutdown();
            } else {
                SMSUtil.sendSMS(primaryKey, this.mConfigInfo.getAccidentUnConfirm(primaryKey), (mAccidentInfo.getTelA() + "," + mAccidentInfo.getTelB()));
                logger.debug("将通知当事去理赔中心处理，同时更改事故状态为已完成");
                //将通知当事去理赔中心处理，同时更改事故状态为已完成
                mAccidenMapper.updateAccidentBaseInfoHandlerAndStatus(primaryKey, Constant.ACCIDENT_PROCESS_OFFICE, AccidentInfo.STATUS_COMPLETE);
                logger.debug("更改事故状态为已完成");
                this.scheduler.shutdown();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
